<?php
declare (strict_types=1);

namespace app\common\queue\notify;

use app\admin\logic\system\notify\NotifyNode;
use app\common\service\BaseService;
use app\course\model\base\Course;
use app\course\model\base\CourseStudent;
use app\course\model\base\StudentCourseNotify;
use app\user\logic\user\SystemNotify;
use app\user\model\user\Account;
use Carbon\Carbon;
use eduline\sms\Client;
use Exception;
use think\facade\Request;
use think\Response;

/**
 * 课程即将到期
 */
class SendStudentCourseExpiredNotify
{

    // 通知节点
    protected $templateCode = 'course_expired';
    /**
     * @var \app\admin\model\system\notify\NotifyNode
     */
    protected $notifyData;

    public function run()
    {
        $data       = Request::post();
        $userId     = $data['user_id'] ?? 0;
        $courseId   = $data['course_id'] ?? 0;
        $expireTime = CourseStudent::where([
            'user_id'   => $userId,
            'course_id' => $courseId
        ])->value('expire_time');
        try {

            // 时间比对
            $day    = Carbon::now()->diffInDays(Carbon::createFromTimestamp($expireTime));
            $status = StudentCourseNotify::where(['user_id' => $userId, 'course_id' => $courseId])->value('expired_status');

            // 是否已经通知完成
            if ($status == 2) {
                return BaseService::parseToData(['status' => 1], 1);
            }
            if ($status == 0 && $day > 7 && $day <= 31) {
                // 课程是否即将到期 : 30天
                $res = $this->sendNotify(1, $data);
                // 更新通知状态
                StudentCourseNotify::update(['expired_status' => 1], ['user_id' => $userId, 'course_id' => $courseId]);

                return $res;
            } else if ($day < 8) {
                // 课程是否即将到期 : 7天
                $res = $this->sendNotify(2, $data);
                // 更新通知状态
                StudentCourseNotify::update(['expired_status' => 2], ['user_id' => $userId, 'course_id' => $courseId]);

                return $res;
            }

            return BaseService::parseToData(['status' => 0], 1);
        } catch (Exception $e) {
            return BaseService::parseToData(['status' => 0], 0);
        }
    }

    /**
     * 课程即将到期通知入口
     *
     * @param int $type 1: 30天内到期 2: 7天内到期
     * @param     $data
     * @return Response
     */
    private function sendNotify(int $type, $data)
    {
        // 初始化通知配置
        $this->initNotifyNodeConfig();
        $userId     = intval($data['user_id'] ?? 0);
        $courseId   = intval($data['course_id'] ?? 0);
        $courseInfo = Course::where('id', $courseId)->field(['title', 'course_type'])->findOrEmpty();
        if (!$courseInfo->isEmpty()) {
            $courseTitle = $courseInfo['title'];
            $courseType  = $this->getCourseTypeAttr(intval($courseInfo['course_type']));

            $this->sendSystem($userId, $courseType, $courseId, $courseTitle);
            $this->sendSms($userId, $courseTitle);
        }

        return BaseService::parseToData(['status' => 1], 1);
    }

    /**
     * 发送系统消息
     *
     * @param int    $userId
     * @param string $courseType
     * @param int    $courseId
     * @param        $courseTitle
     */
    protected function sendSystem(int $userId, string $courseType, int $courseId, $courseTitle)
    {
        if ($this->hasSysNotify()) {
            $content = $this->getSysNotifyContent();
            $content = str_replace(['{{course_title}}'], [$courseTitle], $content);
            // 提醒参数
            $param = [
                'title'          => '课程即将到期提醒',
                'content'        => $content,
                'notify_type'    => 1,    // 1课程提醒 0系统消息
                'is_link'        => 0,
                'link_data_type' => $courseType,
                'link_data_id'   => $courseId,
                'user_id'        => $userId
            ];

            SystemNotify::create($param);
        }
    }

    /**
     * 发送短信
     *
     * @param int $userId
     * @param     $courseTitle
     */
    protected function sendSms(int $userId, $courseTitle)
    {
        if ($this->hasSmsNotify()) {
            $phones       = Account::where('id', $userId)->value('phone');
            $templateCode = $this->getSmsTemplateCode();
            $var          = ['course_title' => $courseTitle];

            Client::send($phones, $var, ['TemplateCode' => $templateCode]);
        }
    }

    /**
     * 课程类型
     *
     * @param $course_type
     * @return string
     */
    protected function getCourseTypeAttr($course_type): string
    {
        $type = [
            1 => 'video',
            2 => 'live',
            3 => 'offline',
            4 => 'classes',
        ];

        return $type[$course_type];
    }

    /**
     * 初始化配置信息
     */
    private function initNotifyNodeConfig()
    {
        $this->notifyData = app(NotifyNode::class)->getNotifyNodeDataByKey($this->templateCode);
    }

    /**
     * 获取短信配置模板
     *
     * @return mixed
     */
    private function getSmsTemplateCode()
    {
        return $this->notifyData->sms_template_code;
    }

    /**
     * 获取系统消息通知内容
     *
     * @return mixed
     */
    private function getSysNotifyContent()
    {
        return $this->notifyData->content;
    }

    /**
     * 是否需要系统消息通知
     *
     * @return bool
     */
    private function hasSysNotify()
    {
        $arr = $this->notifyData->getAttr('open_info');

        if (is_array($arr) && in_array('system_notify', $arr)) {

            return true;
        }

        return false;
    }

    /**
     * 是否需要短信通知
     *
     * @return bool
     */
    private function hasSmsNotify()
    {
        $arr = $this->notifyData->getAttr('open_info');

        if (is_array($arr) && in_array('sms', $arr)) {

            return true;
        }

        return false;
    }
}
